home *** CD-ROM | disk | FTP | other *** search
- .. The Utilities.
-
- "Loading utilities."
-
- Epsilon=epsilon();
- ResetEpsilon=epsilon();
- Pi=pi();
- E=exp(1);
- I=1i;
-
- function reset
- ## reset() resets espilon() and some other things
- global ResetEpsilon;
- setepsilon(ResetEpsilon);
- style(""); hold off;
- color(1);
- shrinkwindow();
- shortformat();
- return 0;
- endfunction
-
- function longformat
- ## longformat() sets a long format for numbers
- return format([20 12]);
- endfunction
-
- function shortformat
- ## shortformat() sets a short format for numbers
- return format([14 5]);
- endfunction;
-
- function linspace (a,b,n)
- ## linspace(a,b,n) generates n+1 linear spaced points in [a,b].
- if a~=b; return a; endif;
- r=a:(b-a)/n:b;
- r[n+1]=b;
- return r;
- endfunction
-
- function equispace (a,b,n)
- ## equispace(a,b,n) generates n+1 euqidistribution (acos) spaced values
- ## in [a,b].
- m=(1-cos(0:pi()/n:pi()))/2;
- return a+(b-a)*m;
- endfunction
-
- function length (v)
- ## length(v) returns the length of a vector
- return max(size(v));
- endfunction
-
- function polydif (p)
- ## polydif(p) returns the polynomial p'
- n=length(p);
- if (n==1); return 0; endif;
- return p[2:n]*(1:n-1);
- endfunction
-
- function writeform (x)
- if isreal(x); return printf("%25.16e",x); endif;
- if iscomplex(x);
- return printf("%25.16e",re(x))|printf("+%25.16ei",im(x));
- endif;
- if isstring(x); return x; endif;
- error("Cannot print this!");
- endfunction
-
- function write (x,s)
- if argn()==1; s=name(x); endif;
- si=size(x);
- if max(si)==1; s|" = "|writeform(x)|";", return 0; endif;
- s|" = [ .."
- for i=1 to si[1];
- for j=1 to si[2]-1;
- writeform(x[i,j])|",",
- end;
- if i==si[1]; writeform(x[i,si[2]])|"];",
- else; writeform(x[i,si[2]])|";",
- endif;
- end;
- return 0
- endfunction
-
- .. ### plot things ###
-
- function title (text)
- ## title(text) plots a title to the grafik window.
- ctext(text,[512 0]);
- return text;
- endfunction
-
- function textheight
- ## textheight() returns the height of a letter.
- h=textsize();
- return h[2];
- endfunction
-
- function textwidth
- ## textwidth() returns the width of a letter.
- h=textsize();
- return h[1];
- endfunction
-
- function fullwindow
- ## fullwindow() takes the full size (besides a title) for the
- ## plots.
- h=textsize();
- w=window();
- window([12,textheight()*1.5,1011,1011]);
- return w;
- endfunction
-
- function shrinkwindow
- ## shrinkwindow() shrinks the window to allow labels.
- h=textheight(); b=textwidth();
- w=window();
- window([6*b,1.5*h,1023-6*b,1023-3*h]);
- return w;
- endfunction
-
- function setplot
- ## setplot([xmin xmax ymin ymax]) sets the plot coordinates and holds
- ## the plot. Also setplot(xmin,xmax,ymin,ymax).
- ## setplot() resets it.
- if argn()==4; return setplot([arg1,arg2,arg3,arg4]);
- else;
- if argn()==0; scaling(1);
- else; error("Illegal arguments!");
- endif;
- endif;
- return plot();
- endfunction
-
- function ticks (a,b)
- ## returns the proper ticks to be used for intervals [a,b] and
- ## the factor of the ticks.
- tick=10^floor(log(b-a)/log(10)-0.4);
- if b-a>10*tick; tick1=tick*2; else; tick1=tick; endif;
- return {(floor(a/tick1)+1)*tick1:tick1:(ceil(b/tick1)-1)*tick1,tick}
- endfunction
-
- function xplot (x,y)
- ## xplot(x,y) or xplot(y) works like plot, but shows axis ticks.
- if argn()>0;
- if argn()==1;
- if iscomplex(x); y=im(x); xh=re(x);
- else y=x; xh=1:length(y);
- endif;
- else; xh=x;
- endif;
- p=plot(xh,y);
- else
- if !holding(); clg; endif;
- p=plot(); frame();
- endif;
- {t,f}=ticks(p[1],p[2]); xgrid(t,f);
- {t,f}=ticks(p[3],p[4]); ygrid(t,f);
- return p;
- endfunction
-
- function xmark (x,y)
- ## xmark(x,y) or xmark(y) works like plot, but shows axis ticks.
- if argn()==1;
- if iscomplex(x); y=im(x); xh=re(x);
- else; y=x; xh=1:length(y);
- endif;
- else; xh=x;
- endif;
- p=mark(xh,y);
- {t,f}=ticks(p[1],p[2]); xgrid(t,f);
- {t,f}=ticks(p[3],p[4]); ygrid(t,f);
- return p;
- endfunction
-
- function fplot (ffunction,a,b)
- ## fplot("f",a,b,...) plots the function f in [a,b].
- ## The arguments ... are passed to f.
- t=linspace(a,b,200);
- s=ffunction(t,args(4));
- return xplot(t,s)
- endfunction
-
- function printscale (x)
- if (abs(x)>10000) || (abs(x)<0.00001);
- return printf("%12.5e",x);
- else
- return printf("%10.5f",x);
- endif;
- endfunction
-
- function xgrid
- ## xgrid([x0,x1,...]) draws vertical grid lines on the plot window at
- ## x0,x1,...
- ## xgrid([x0,x1,...],f) additionally writes x0/f to the axis.
- c=plot(); n=length(arg1); s=scaling(0); h=holding(1);
- w=window();
- style("."); color(3);
- ht=textheight();
- loop 1 to n;
- x=arg1[index()];
- if (x<=c[2])&&(x>=c[1]);
- plot([x,x],[c[3],c[4]]);
- if (argn()==2);
- col=w[1]+(x-c[1])/(c[2]-c[1])*(w[3]-w[1]);
- ctext(printf("%4.0lf",x/arg2),[col,w[4]+0.2*ht]);
- endif;
- endif;
- end;
- if (argn()==2);
- ctext("* "|printscale(arg2),[(w[1]+w[3])/2,w[4]+1.5*ht]);
- endif;
- style(""); color(1); holding(h); scaling(s);
- return 0;
- endfunction
-
- function ygrid
- ## xgrid([x0,x1,...]) draws horizontal grid lines on the plot window at
- ## x0,x1,...
- ## xgrid([x0,x1,...],f) additionally writes x0/f to the axis.
- c=plot(); n=length(arg1); s=scaling(0); h=holding(1);
- style("."); color(3);
- w=window(); wd=textwidth(); ht=textheight();
- loop 1 to n;
- y=arg1[index()];
- if (y>=c[3])&&(y<=c[4]);
- if (argn()==2);
- row=w[4]-(y-c[3])/(c[4]-c[3])*(w[4]-w[2]);
- text(printf("%4.0lf",y/arg2),[w[1]-6*wd,row-ht/2]);
- endif;
- plot([c[1],c[2]],[y,y]);
- endif;
- end;
- if (argn()==2);
- text("* "|printscale(arg2),[w[1]-6*wd,0]);
- endif;
- style(""); color(1); holding(h); scaling(s);
- return 0;
- endfunction
-
- function plot (x,y)
- ## plot(x,y) plots the values (x(i),y(i)) with the current style.
- ## If x is a matrix, y must be a matrix of the same size.
- ## The plot is then drawn for all rows of x and y.
- ## The plot is scaled automatically, unless hold is on.
- ## plot(x,y) and plot() return [x1,x2,y1,y2], where [x1,x2] is the range
- ## of the x-values and [y1,y2] of the y-values.
- ## plot(x) is the same as plot(1:length(x),x).
- if argn()==1;
- if iscomplex(x); return plot(re(x),im(x));
- else return plot(1:length(x),x);
- endif;
- endif;
- error("Illegal argument number!"),
- endfunction
-
- function mark (x,y)
- ## mark(x,y) plots markers at (x(i),y(i)) according the the actual style.
- ## Works like plot.
- if argn()==1;
- if iscomplex(x); return mark(re(x),im(x));
- else return mark(1:length(x),x);
- endif;
- endif;
- error("Illegal argument number!"),
- endfunction
-
- function cplot (z)
- ## cplot(z) plots a grid of complex numbers.
- plot(re(z),im(z)); s=scaling(0); h=holding(1);
- w=z'; plot(re(w),im(w)); holding(h); scaling(s);
- return plot();
- endfunction
-
- function plotwindow
- ## plotwindow() sets the plot window to the screen coordinates.
- w=window();
- setplot(w[1],w[3],w[2],w[4]);
- return plot()
- endfunction
-
- function getframe (x,y,z)
- ## gets the a box around all points in (x,y,z).
- ex=extrema(x); ey=extrema(y); ez=extrema(z);
- return [min(ex[:,1]'),max(ex[:,3]'),
- min(ey[:,1]'),max(ey[:,3]'),min(ez[:,1]'),max(ez[:,3]')]
- endfunction
-
- function framez0 (f)
- wire([f[1],f[2],f[2],f[1],f[1]], ..
- [f[3],f[3],f[4],f[4],f[3]],dup(f[5],5)');
- return 0
- endfunction
-
- function framez1 (f)
- wire([f[1],f[2],f[2],f[1],f[1]], ..
- [f[3],f[3],f[4],f[4],f[3]],dup(f[6],5)');
- return 0
- endfunction
-
- function framexpyp (f)
- wire([f[2],f[2]],[f[4],f[4]],[f[5],f[6]]);
- return 0
- endfunction
-
- function framexpym (f)
- wire([f[2],f[2]],[f[3],f[3]],[f[5],f[6]]);
- return 0
- endfunction
-
- function framexmyp (f)
- wire([f[1],f[1]],[f[4],f[4]],[f[5],f[6]]);
- return 0
- endfunction
-
- function framexmym (f)
- wire([f[1],f[1]],[f[3],f[3]],[f[5],f[6]]);
- return 0
- endfunction
-
- function frame1 (f)
- ## draws the back part of the box (considering view)
- v=view();
- if v[4]>0; framez0(f);
- else; framez1(f); endif;
- if sin(v[3])>0;
- framexmyp(f); framexmym(f);
- if cos(v[3])>0; framexpyp(f); else; framexpym(f); endif;
- else
- framexpyp(f); framexpym(f);
- if cos(v[3])>0; framexmyp(f); else; framexmym(f); endif;
- endif;
- return 0
- endfunction
-
- function frame2 (f)
- ## draws the back part of the box (considering view).
- v=view();
- if v[4]>0; framez1(f);
- else; framez0(f); endif;
- if sin(v[3])>0;
- if cos(v[3])>0; framexpym(f); else; framexpyp(f); endif;
- else
- if cos(v[3])>0; framexmym(f); else; framexmyp(f); endif;
- endif;
- return 0
- endfunction
-
- function scaleframe (x,y,z,f,m)
- s=max([f[2]-f[1],f[4]-f[3],f[6]-f[5]]);
- xm=(f[2]+f[1])/2;
- ym=(f[4]+f[3])/2;
- zm=(f[6]+f[5])/2;
- ff=m/s*2;
- f=[f[1]-xm,f[2]-xm,f[3]-ym,f[4]-ym,f[5]-zm,f[6]-zm]*ff;
- return {(x-xm)*ff,(y-ym)*ff,(z-zm)*ff}
- endfunction
-
- function framedsolid (x,y,z,f)
- ## works like solid and draws a frame around the plot
- ## if f is specified, then the plot is scaled to fit into a cube of
- ## side length 2f centered at 0
- frame=getframe(x,y,z);
- if !holding(); clg; endif;
- h=holding(1);
- if argn()==4; {x1,y1,z1}=scaleframe(x,y,z,frame,f);
- else; {x1,y1,z1}={x,y,z}; endif;
- color(2); frame1(frame);
- color(1); solid(x1,y1,z1);
- color(2); frame2(frame);
- color(1);
- holding(h);
- return frame
- endfunction
-
- function framedwire (x,y,z,f)
- ## works like framedsolid
- frame=getframe(x,y,z);
- if !holding(); clg; endif;
- h=holding(1);
- if argn()==4; {x1,y1,z1}=scaleframe(x,y,z,frame,f);
- else; {x1,y1,z1}={x,y,z}; endif;
- color(2); frame1(frame);
- color(1); wire(x1,y1,z1);
- color(2); frame2(frame);
- color(1);
- holding(h);
- return frame
- endfunction
-
- .. ### linear algebra things ###
-
- function id (n)
- ## id(n) creates a nxn identity matrix.
- return diag([n n],0,1);
- endfunction
-
- function inv (a)
- ## inv(a) produces the inverse of a matrix.
- return a\id(length(a));
- endfunction
-
- function fit (a,b)
- ## fit(a,b) computes x such that ||a.x-b||_2 is minimal.
- A=conj(a');
- return symmult(A,a)\(A.b')
- endfunction
-
- function kernel (a)
- ## kernel(a) computes the kernel of the quadratic matrix a.
- {aa,r,c,d}=lu(a);
- n=size(a);
- if length(r)==n[2] return zeros([1,n[2]])'; endif;
- c1=nonzeros(c); c2=nonzeros(!c);
- b=lusolve(aa[r,c1],a[r,c2]);
- m=size(b);
- x=zeros([n[2] m[2]]);
- x[c1,:]=-b;
- x[c2,:]=id(length(c2));
- return x
- endfunction
-
- function image (a)
- ## image(a) computes the image of the quadratic matrix a.
- {aa,r,c,d}=lu(a);
- return a[:,nonzeros(c));
- endfunction
-
- function det (a)
- ## det(A) returns the determinant of A
- {aa,r,c,d}=lu(a);
- return d;
- endfunction
-
- function eigenvalues (a)
- ## eigenvalues(A) returns the eigenvalues of A.
- return polysolve(charpoly(a));
- endfunction
-
- function eigenspace (a,l)
- ## eigenspace(A,l) returns the eigenspace of A to the eigenvaue l.
- k=kernel(a-l*id(length(a)));
- if k==0; error("No eigenvalue found!"); endif;
- si=size(k);
- loop 1 to si[2];
- x=k[:,index()];
- k[:,index()]=x/sqrt(x'.x);
- end;
- return k;
- endfunction
-
- function eigen (A)
- ## eigen(A) returns the eigenvectors and a basis of eigenvectors of A.
- ## {l,x}=eigen(A), where l is a vector of distinct eigenvalues and
- ## x is a basis of eigenvectors.
- l=eigenvalues(A);
- s=eigenspace(A,l[1]);
- si=size(s); v=l[1]; l=eigenremove(l,si[2]);
- repeat;
- if min(size(l))==0; break; endif;
- ll=l[1]; sp=eigenspace(A,ll);
- si=size(sp); l=eigenremove(l,si[2]);
- s=s|sp; v=v|ll;
- end;
- return {v,s}
- endfunction
-
-
- function eigenspace1
- ## eigenspace1(A,l) returns the eigenspace of A to the eigenvalue l.
- ## returns {x,l1}, where l1 should be an improvement over l, and
- ## x contains the eigenvectors as columns.
- eps=epsilon();
- repeat;
- k=kernel(arg1-arg2*id(length(arg1)));
- if k==0; else; break; endif;
- if epsilon()>1 break; endif;
- setepsilon(100*epsilon());
- end;
- if k==0; error("No eigenvalue found!"); endif;
- setepsilon(eps);
- {dummy,l}=eigennewton(arg1,k[:,1],arg2);
- eps=epsilon();
- repeat;
- k=kernel(arg1-l*id(length(arg1)));
- if k==0; else; break; endif;
- if epsilon()>1 break; endif;
- setepsilon(100*epsilon());
- end;
- if k==0; error("No eigenvalue found!"); endif;
- setepsilon(eps);
- si=size(k);
- loop 1 to si[2];
- x=k[:,index()];
- k[:,index()]=x/sqrt(x'.x);
- end;
- return {k,l};
- endfunction
-
- function eigenremove
- ## helping function.
- {l,n}={arg1,arg2};
- k=length(l); l1=l[2:k];
- if n==1; return l1; endif;
- v=abs(l[1]-l1);
- {vs,i}=sort(v);
- return(l1[i[n:k]]);
- endfunction
-
- function eigen1
- ## eigen1(A) returns the eigenvectors and a basis of eigenvectors of A.
- ## {l,x}=eigen(A), where l is a vector of distinct eigenvalues and
- ## x is a basis of eigenvectors. Improved version of eigen.
- l=eigenvalues(arg1);
- {s,ll}=eigenspace1(arg1,l[1]); l[1]=ll;
- si=size(s); v=l[1]; l=eigenremove(l,si[2]);
- repeat;
- if min(size(l))==0; break; endif;
- ll=l[1];
- {sp,ll}=eigenspace1(arg1,ll); l[1]=ll;
- si=size(sp); l=eigenremove(l,si[2]);
- s=s|sp; v=v|ll;
- end;
- return {v,s}
- endfunction
-
- function eigennewton
- ## eigennewton(a,x,l) does a newton step to improve the eigenvalue l
- ## of a and the eigenvector x.
- ## returns {x1,l1}.
- a=arg1; x=arg2; x=x/sqrt(x'.x); n=length(a);
- d=((a-arg3*id(n))|-x)_(2*x'|0);
- b=d\((a.x-arg3*x)_0);
- return {x-b[1:n],arg3-b[n+1]};
- endfunction
-
- hilbfactor=5*7*8*27*11*13*17*19*23*29;
-
- function hilb (n)
- ## hilb(n) produces the nxn-Hilbert matrix, multiplied by hilbfactor.
- global hilbfactor;
- {i,j}=field(1:n,1:n);
- return hilbfactor/(i+j-1);
- endfunction
-
- .. ### polynomial fit ##
-
- function polyfit (xx,yy,n)
- ## fit(x,y,degree) fits a polynomial in L_2-norm to (x,y).
- A=ones(size(xx))_dup(xx,n); A=cumprod(A');
- return fit(A,yy)';
- endfunction
-
- function field (x,y)
- ## field(x,y) returns {X,Y} such that the X+i*Y is a rectangular
- ## grid in C containing the points x(n)+i*y(m).
- return {dup(x,length(y)),dup(y',length(x))};
- endfunction
-
- function totalsum (A)
- ## totalsum(a) computes the sum of all elements of a
- return sum(sum(A)');
- endfunction
-
- function sinh
- ## sinh(x) = (exp(x)-exp(-x))/2
- h=exp(arg1);
- return (h-1/h)/2;
- endfunction
-
- function cosh
- ## cosh(x) = (exp(x)+exp(-x))/2
- h=exp(arg1);
- return (h+1/h)/2;
- endfunction
-
- function arsinh
- ## arsinh(z) = log(z+sqrt(z^2+1))
- return log(arg1+sqrt(arg1*arg1+1))
- endfunction
-
- function arcosh
- ## arcosh(z) = log(z+(z^2-1))
- return log(arg1+sqrt(arg1*arg1-1))
- endfunction
-
- function heun (ffunction,t,y0)
- ## y=heun("f",t,y0,...) solves the differential equation y'=f(t,y).
- ## f(t,y,...) must be a function.
- ## y0 is the starting value.
- n=length(t);
- y=dup(y0,n);
- loop 1 to n-1;
- h=t[#+1]-t[#];
- yh=y[#]; xh=t[#];
- k1=ffunction(xh,yh,args(4));
- k2=ffunction(xh+h/2,yh+h/2*k1,args(4));
- k3=ffunction(xh+h,yh+2*h*k2-h*k1,args(4));
- y[#+1]=yh+h/6*(k1+4*k2+k3);
- end;
- return y';
- endfunction
-
- solveeps=epsilon();
-
- function bisect (ffunction,a,b)
- ## bisect("f",a,b,...) uses the bisection method to find a root of
- ## f in [a,b].
- global solveeps;
- if ffunction(b,args(4))<0;
- b1=a; a1=b;
- else;
- a1=a; b1=b;
- endif;
- if ffunction(b1,args(4))<0 error("No zero in interval"); endif;
- repeat
- m=(a1+b1)/2;
- if abs(a1-b1)<solveeps; return m; endif;
- if ffunction(m,args(4))>0; b1=m; else a1=m; endif;
- end;
- endfunction
-
- function secant (ffunction,a,b)
- ## secant("f",a,b,...) uses the secant method to find a root of f in [a,b]
- global solveeps;
- x0=a; x1=b; y0=ffunction(x0,args(4)); y1=ffunction(x1,args(4));
- repeat
- x2=x1-y1*(x1-x0)/(y1-y0);
- if abs(x2-x1)<solveeps; break; endif;
- x0=x1; y0=y1; x1=x2; y1=ffunction(x2,args(4));
- end;
- return x2
- endfunction
-
- function simpson (ffunction,a,b)
- ## simpson("f",a,b) or simpson("f",a,b,n,...) integrates f in [a,b] with
- ## the simpson method. f must be able to evaluate a vector.
- if argn()>=4; n=arg4; else; n=50; endif;
- t=linspace(a,b,2*n);
- s=ffunction(t,args(5));
- ff=4-mod(1:2*n+1,2)*2; ff[1]=1; ff[2*n+1]=1;
- return sum(ff*s)/3*(t[2]-t[1]);
- endfunction
-
- rombergeps=epsilon();
-
- function romberg(ffunction,a,b,m)
- ## romberg(f,a,b) computes the Romberg integral of f in [a,b].
- ## romberg(f,a,b,m,...) specifies h=(b-a)/m/2^k for k=1,...
- ## ... is passed to f(x,...)
- global rombergeps;
- if argn()==3; m=10; endif;
- y=ffunction(linspace(a,b,m),args(5)); h=(b-a)/m;
- y[1]=y[1]/2; y[m+1]=y[m+1]/2; I=sum(y);
- S=I*h; H=h^2; Intalt=S;
- repeat;
- I=I+sum(ffunction(a+h/2:h:b,args(5))); h=h/2;
- S=S|I*h;
- H=H|h^2;
- Int=interpval(H,interp(H,S),0);
- if abs(Int-Intalt)<rombergeps; break; endif;
- Intalt=Int;
- end;
- return Intalt
- endfunction
-
- gaussz = [ ..
- -9.7390652851717172e-0001,
- -8.6506336668898451e-0001,
- -6.7940956829902441e-0001,
- -4.3339539412924719e-0001,
- -1.4887433898163121e-0001,
- 1.4887433898163121e-0001,
- 4.3339539412924719e-0001,
- 6.7940956829902440e-0001,
- 8.6506336668898451e-0001,
- 9.7390652851717172e-0001];
- gaussa = [ ..
- 6.6671344308688139e-0002,
- 1.4945134915058059e-0001,
- 2.1908636251598205e-0001,
- 2.6926671930999635e-0001,
- 2.9552422471475288e-0001,
- 2.9552422471475287e-0001,
- 2.6926671930999635e-0001,
- 2.1908636251598205e-0001,
- 1.4945134915058059e-0001,
- 6.6671344308688137e-0002];
-
- function gauss10 (ffunction,a,b)
- ## gauss10("f",a,b,...)
- ## evaluates the gauss integration with 10 knots an [a,b]
- global gaussa,gaussz;
- z=a+(gaussz+1)*(b-a)/2;
- return sum(gaussa*ffunction(z,args(4)))*(b-a)/2;
- endfunction
-
- function gauss (ffunction,a,b,n)
- ## gauss("f",a,b) gauss integration with 10 knots
- ## gauss("f",a,b,n,...) subdivision into n subintervals.
- ## a and b may be vectors.
- si=size(a,b); R=zeros(si);
- if argn()==3;
- loop 1 to prod(si);
- sum=0;
- sum=sum+gauss10(ffunction,a{#},b{#});
- R{#}=sum;
- end;
- else;
- loop 1 to prod(si);
- h=linspace(a{#},b{#},n); sum=0;
- loop 1 to n;
- sum=sum+gauss10(ffunction,h{#},h{#+1},args(5));
- end;
- R{#}=sum;
- end;
- endif;
- return R
- endfunction
-
- .. ### Broyden ###
-
- broydenmax=50;
-
- function broyden (ffunction,xstart,A)
- ## broyden("f",x) or broyden("f",x,a,...) finds a zero of f.
- ## x is the starting value and a is a approximation of the jacobian.
- ## if a is 0, it is neglected.
- ## ... is passed to f(x,...)
- global solveeps;
- x=xstart; n=length(x);
- global broydenmax;
- delta=sqrt(solveeps);
- if argn()==2; A=0; endif;
- if A==0;
- A=zeros([n n]);
- y=ffunction(x,args(4));
- loop 1 to n;
- x0=x; x0[#]=x0[#]+delta;
- A[:,#]=(ffunction(x0,args(4))-y)'/delta;
- end;
- endif;
- itercount=0;
- y=ffunction(x,args(4));
- repeat
- d=-A\y'; x=x+d';
- y1=ffunction(x,args(4)); q=y1-y;
- A=A+((q'-A.d).d')/(d'.d);
- if (max(abs(d))<solveeps || itercount>broydenmax) break; endif;
- y=y1;
- itercount=itercount+1;
- end;
- if (itercount>broydenmax) error("Iteration failed"); endif;
- return x;
- endfunction
-
- function map (ffunction,t)
- ## map("f",t,...) evaluates the function f at all points of the vector t.
- ## usually this is the same as f(t,...), but sometimes functions do not
- ## accept vectors as input.
- si=size(t); s=zeros(si);
- loop 1 to prod(si); s{#}=ffunction(t{#},args(3)); end;
- return s;
- endfunction
-
- itereps=epsilon();
-
- function iterate (ffunction,x,n)
- ## iterate("f",x,n,...) iterate the function f(x,...) n times,
- ## starting with the point x.
- ## if n is missing or n is 0, then the iteration stops at a fixed point.
- ## Returns the value after n iterations, and its history.
- global itereps;
- if argn()<3; n=0; endif;
- if n==0;
- R=x; Rold=x;
- repeat
- Rnew=ffunction(Rold,args(4));
- R=R_Rnew;
- if max(abs(Rold-Rnew))<itereps; return Rnew; endif;
- Rold=Rnew;
- end;
- else;
- R=zeros(n,length(x));
- R[1]=x;
- loop 2 to n; R[#]=ffunction(R[#-1],args(4)); end;
- return {R[n],R'}
- endif;
- endfunction
-
- .. ### Remez algorithm ###
-
- function remezhelp (x,y,n)
- ## {t,d,h}=remezhelp(x,y,deg) is the case, where x are exactly deg+2
- ## points.
- d1=interp(x,y); d2=interp(x,mod(1:n+2,2)*2-1);
- h=d1[n+2]/d2[n+2];
- d=d1-d2*h;
- return {x[1:n+1],d[1:n+1],h};
- endfunction
-
- remezeps=0.00001;
-
- function remez
- ## {t,d,h,r}=remez(x,y,deg) computes the divided difference form
- ## of the polynomial best approximation to y at x of degree deg.
- ## remez(x,y,deg,1) does the same thing with tracing.
- ## h is the discrete error (with sign), and x the rightmost point,
- ## which is missing in t.
- global remezeps;
- if argn()==4; trace=1; else; trace=0; endif;
- x=arg1; y=arg2; deg=arg3; n=length(x);
- ind=linspace(1,n,deg+1); h=0;
- repeat
- {t,d,hnew}=remezhelp(x[ind],y[ind],deg);
- r=y-interpval(t,d,x); hh=hnew;
- if trace;
- xind=x[ind];
- plot(x,r); xgrid(xind); ygrid([-h,0,h]);
- title("Weiter mit Taste"); wait(180);
- endif;
- indnew=ind; rr=ind;
- rr[1]=r[ind[1]];
- rr[2]=r[ind[deg+2]];
- loop 2 to deg+1;
- e=extrema(r[ind[index()-1]:ind[index()+1]]);
- if (hh>0);
- indnew[index()]=e[2]+ind[index()-1]; rr[index()]=e[1];
- else
- indnew[index()]=e[4]+ind[index()-1]; rr[index()]=e[3];
- endif;
- hh=-hh;
- end;
- ind=indnew;
- if (abs(hnew)<(1+remezeps)*abs(h)) break; endif;
- h=hnew;
- end;
- {t,d,h}=remezhelp(x[ind],y[ind],deg);
- if trace;
- xind=x[ind];
- plot(x,y-interpval(t,d,x)); xgrid(xind); ygrid([-h,0,h]);
- title("Weiter mit Taste"); wait(180);
- endif;
- return {t,d,h,x[ind[deg+2]]};
- endfunction
-
- .. ### Natural spline ###
-
- function spline (x,y)
- ## spline(x,y) defines the natural Spline at points x(i) with
- ## values y(i). It returns the second derivatives at these points.
- n=length(x);
- h=x[2:n]-x[1:n-1];
- s=h[2:n-1]+h[1:n-2];
- l=h[2:n-1]/s;
- A=diag([n,n],0,2);
- A=setdiag(A,1,0|l);
- A=setdiag(A,-1,1-l|0);
- b=6/s*((y[3:n]-y[2:n-1])/h[2:n-1]-(y[2:n-1]-y[1:n-2])/h[1:n-2]);
- return (A\(0|b|0)')';
- endfunction
-
- function splineval (x,y,h,t)
- ## splineval(x,y,h,t) evaluates the interpolation spline for
- ## (x(i),y(i)) with second derivatives h(i) at t.
- p1=find(x,t); p2=p1+1;
- y1=y[p1]; y2=y[p2];
- x1=x[p1]; x2=x[p2]; f=(x2-x1)^2;
- h1=h[p1]*f; h2=h[p2]*f;
- b=h1/2; c=(h2-h1)/6;
- a=y2-y1-b-c;
- d=(t-x1)/(x2-x1);
- return y1+d*(a+d*(b+c*d));
- endfunction
-
- .. ### use zeros,... the usual way ###
-
- function ctext
- ## ctext(s,[c,r]) plots the centered string s at the coordinates (c,r).
- ## Also ctext(s,c,r).
- if argn()==3; return ctext(arg1,[arg2,arg3]); endif;
- error("Illegal argument number!"),
- endfunction
-
- function text
- ## text(s,[c,r]) plots the centered string s at the coordinates (c,r).
- ## Also ctext(s,c,r).
- if argn()==3; return text(arg1,[arg2,arg3]); endif;
- error("Illegal argument number!"),
- endfunction
-
- function diag
- ## diag([n,m],k,v) returns a nxm matrix A, containing v on its k-th
- ## diagonal. v may be a vector or a real number. Also diag(n,m,k,v);
- ## diag(A,k) returns the k-th diagonal of A.
- if argn()==4; return diag([arg1,arg2],arg3,arg4); endif;
- error("Illegal argument number!"),
- endfunction
-
- function format
- ## format([n,m]) sets the number output format to m digits and a total
- ## width of n. Also format(n,m);
- if argn()==2; return format([arg1,arg2]); endif;
- error("Illegal argument number!"),
- endfunction
-
- function normal
- ## normal([n,m]) returns a nxm matrix of unit normal distributed random
- ## values. Also normal(n,m).
- if argn()==2; return normal([arg1,arg2]); endif;
- error("Illegal argument number!"),
- endfunction
-
- function random
- ## random([n,m]) returns a nxm matrix of uniformly distributed random
- ## values in [0,1]. Also random(n,m).
- if argn()==2; return random([arg1,arg2]); endif;
- error("Illegal argument number!"),
- endfunction
-
- function ones
- ## ones([n,m]) returns a nxm matrix with all elements set to 1.
- ## Also ones(n,m).
- if argn()==2; return ones([arg1,arg2]); endif;
- error("Illegal argument number!"),
- endfunction
-
- function zeros
- ## zeros([n,m]) returns a nxm matrix with all elements set to 0.
- ## Also zeros(n,m).
- if argn()==2; return zeros([arg1,arg2]); endif;
- error("Illegal argument number!"),
- endfunction
-
- function matrix
- ## matrix([n,m],x) returns a nxm matrix with all elements set to x.
- ## Also matrix(n,m,x).
- if argn()==3; return matrix([arg1,arg2],arg3); endif;
- error("Illegal argument number!"),
- endfunction
-
- function view
- ## view([distance, tele, angle1, angle2]) sets the perspective for
- ## solid and view. distance is the eye distance, tele a zooming factor.
- ## angle1 is the angle from the negativ y-axis to the positive x-axis.
- ## angle2 is the angle to the positive z-axis (the height of the eye).
- ## Also view(d,t,a1,a2).
- ## view() returns the values of view.
- if argn()==4; return view([arg1,arg2,arg3,arg4]); endif;
- error("Illegal argument number!"),
- endfunction
-
- function window
- ## window([c1,r1,c2,r2]) sets a plotting window. The cooridnates must
- ## be screen coordimates. Also window(c1,r1,c2,r2).
- ## window() returns the active window coordinates.
- if argn()==4; return window([arg1,arg2,arg3,arg4]); endif;
- error("Illegal argument number!"),
- endfunction
-
- .. *** directory ***
-
- function dir(pattern)
- ## dir(pattern) displays a directory.
- ## dir() is the same as dir("*.*").
- if argn()==0; pattern="*.*"; endif;
- s=searchfile(pattern), if stringcompare(s,"")==0; return 0; endif;
- repeat
- s=searchfile(), if stringcompare(s,"")==0; return 0; endif;
- end;
- endfunction
-
-